package com.jswlw.service.biz.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jswlw.common.BaseException;
import com.jswlw.common.ResponseStatus;
import com.jswlw.dao.biz.DevInfoMapper;
import com.jswlw.entity.biz.*;
import com.jswlw.entity.biz.log.LogDevOpt;
import com.jswlw.entity.biz.log.LogHeart;
import com.jswlw.service.biz.*;
import com.jswlw.service.biz.log.LogDevOptService;
import com.jswlw.service.biz.log.LogHeartService;
import com.jswlw.service.helper.DevApiHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
public class DevInfoServiceImpl implements DevInfoService {
    @Autowired
    DevInfoMapper mapper;
    @Autowired
    DevFilterService devFilterService;
    @Autowired
    DevTypeService devTypeService;
    @Autowired
    DevApiHelper devApiHelper;
    @Autowired
    LogDevOptService logDevOptService;
    @Autowired
    LogHeartService logHeartService;
    @Autowired
    DistributorAmountConsumeService distributorAmountConsumeService;
    @Autowired
    DevSetService devSetService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(DevInfo devInfo) {
        //初始化设备信息
        devInfo.setDevStatus(1);
        devInfo.setRemainFlow(0);
        devInfo.setUsedFlow(0);
        devInfo.setRemainTime(0);
        devInfo.setUsedTime(0);
        devInfo.setPurityTds(0);
        devInfo.setRawTds(0);
        devInfo.setOnlineStatus(0);
        devInfo.setAsignal(0);
        devInfo.setOnlineTime(new Date());
        devInfo.setCreateTime(new Date());
        devInfo.setBindStatus(0);
        devInfo.setRepairNum(0);
        devInfo.setCreateTime(new Date());
        mapper.insertSelective(devInfo);

    }

    @Override
    public void update(DevInfo devInfo) {
        mapper.updateByPrimaryKeySelective(devInfo);
    }

    @Override
    public void bind(DevInfo devInfo) {
        DevType devType = devTypeService.find4Id(devInfo.getDevTypeId());
        if (devType != null && !CollectionUtils.isEmpty(devType.getFilterInfoList())) {
            devFilterService.delete4DevId(devInfo.getId());
            for (int i = 0; i < devType.getFilterInfoList().size(); i++) {
                FilterInfo filterInfo = devType.getFilterInfoList().get(i);
                DevFilter devFilter = new DevFilter();
                devFilter.setDevId(devInfo.getId());
                devFilter.setFilterId(filterInfo.getId());
                devFilter.setInitCount(0);
                devFilter.setUsed(0);
                devFilter.setSort(i + 1);
                if (devInfo.getBillTypeId() == 0) {
                    devFilter.setMaxValue(filterInfo.getFlux());
                } else if (devInfo.getBillTypeId() == 1) {
                    devFilter.setMaxValue(filterInfo.getDuration());
                } else {
                    devFilter.setMaxValue(filterInfo.getFlux());
                }
                devFilterService.add(devFilter);
            }
        }
        devInfo.setCreateTime(new Date());
        devInfo.setBindTime(new Date());
        mapper.updateByPrimaryKeySelective(devInfo);
    }

    @Override
    public void delete(String id) {
        mapper.deleteByPrimaryKey(id);
    }

    @Override
    public DevInfo find4Id(String id) {
        DevInfo devInfo = mapper.selectByPrimaryKey(id);
        if (Objects.isNull(devInfo)) {
            BaseException.sneakyThrows(ResponseStatus.BUSINESS_ERROR.getCode(), "设备不存在");
        }
        LogHeart logHeart = logHeartService.findLastHeart(devInfo.getImei());
        if (Objects.nonNull(logHeart)) {
            if ((System.currentTimeMillis() - logHeart.getCreateTime()) > (1000 * 60 * 3)) {
                devInfo.setOnlineStatus(0);
            } else {
                devInfo.setOnlineStatus(1);
            }
        } else {
            devInfo.setOnlineStatus(0);
        }
        return devInfo;
    }

    @Override
    public DevInfo find4Imei(String imei) {
        DevInfo devInfo = mapper.find4Imei(imei);
        if (Objects.isNull(devInfo)) {
            return devInfo;
        }
        LogHeart logHeart = logHeartService.findLastHeart(devInfo.getImei());
        if (Objects.nonNull(logHeart)) {
            if ((logHeart.getCreateTime() - System.currentTimeMillis()) > (1000 * 60 * 3)) {
                devInfo.setOnlineStatus(1);
            } else {
                devInfo.setOnlineStatus(0);
            }
        } else {
            devInfo.setOnlineStatus(0);
        }
        return devInfo;
    }


    @Override
    public List<DevInfo> queryList(DevInfo filter) {
        return mapper.queryList(filter);
    }

    @Override
    public Page<DevInfo> queryPage(DevInfo devInfo, Integer offset, Integer limit) {
        PageHelper.startPage(offset, limit);
        return (Page<DevInfo>) mapper.queryList(devInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void filterInit(String devId, Integer level) {
        devApiHelper.filterUpdate(mapper.selectByPrimaryKey(devId).getImei(), (byte) level.intValue(), (byte) 0xFF, (byte) 0xFF);
    }

    @Override
    public void start(String id) {
        DevInfo devInfo = new DevInfo();
        devInfo.setOnlineStatus(1);
        devInfo.setId(id);
        mapper.updateByPrimaryKeySelective(devInfo);
        devApiHelper.startUp(mapper.selectByPrimaryKey(id).getImei(), (byte) 0x01);
        DevInfo info = mapper.selectByPrimaryKey(id);
        logDevOptService.add(LogDevOpt.builder()
                .res(id)
                .imei(info.getImei())
                .devId(info.getId())
                .opt("开机")
                .createUserId(1)
                .createTime(new Date())
                .build());
    }

    @Override
    public void stop(String id) {
        DevInfo devInfo = new DevInfo();
        devInfo.setOnlineStatus(0);
        devInfo.setId(id);
        mapper.updateByPrimaryKeySelective(devInfo);
        devApiHelper.shutDown(mapper.selectByPrimaryKey(id).getImei(), (byte) 0x01);
        DevInfo info = mapper.selectByPrimaryKey(id);
        logDevOptService.add(LogDevOpt.builder()
                .res(id)
                .imei(info.getImei())
                .devId(info.getId())
                .opt("关机")
                .createUserId(1)
                .createTime(new Date())
                .build());
    }

    @Override
    public void force(String id) {
        devApiHelper.forceWash(mapper.selectByPrimaryKey(id).getImei(), (byte) 0x01);
        DevInfo info = mapper.selectByPrimaryKey(id);
        logDevOptService.add(LogDevOpt.builder()
                .res(id)
                .imei(info.getImei())
                .devId(info.getId())
                .opt("强冲")
                .createUserId(1)
                .createTime(new Date())
                .build());
    }

    @Override
    public void devInit(String id) {
        DevSet devSet = new DevSet();
        devSet.setDevId(id);
        devSet.setLl2sc(10);
        devSet.setPumpWorkTime(90);
        devSet.setWashTime(18);
        devSet.setWashFixedTime(360);
        devSet.setServiceTime(360);
        devSetService.update(devSet);
        devApiHelper.wipe(mapper.selectByPrimaryKey(id).getImei());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void filterInit(String devId) {
        devApiHelper.filterUpdate(devId, (byte) 0x01, (byte) 0x01, (byte) 0x01);
    }

    @Override
    public void unBind(String id) {
        DevInfo devInfo = mapper.selectByPrimaryKey(id);
        DevInfo updateDevInfo = new DevInfo();
        updateDevInfo.setBindStatus(0);
        updateDevInfo.setUserId(null);
        updateDevInfo.setDistributorId(null);
        updateDevInfo.setDistributorName(null);
        updateDevInfo.setImei(devInfo.getImei());
        updateDevInfo.setId(devInfo.getId());

        mapper.updateByPrimaryKey(updateDevInfo);
        DevInfo info = mapper.selectByPrimaryKey(id);
        logDevOptService.add(LogDevOpt.builder()
                .res(id)
                .imei(info.getImei())
                .devId(info.getId())
                .opt("解绑")
                .createUserId(1)
                .createTime(new Date())
                .build());
    }

    @Override
    public void subMoney(String id, Integer amount) {
        DevInfo devInfo = mapper.selectByPrimaryKey(id);
        devApiHelper.subMoney(mapper.selectByPrimaryKey(id).getImei(), amount);

        DistributorAmountConsume distributorAmountConsume = new DistributorAmountConsume();
        if (devInfo.getBillTypeId().equals(0)) {
            distributorAmountConsume.setLl(-amount);
        } else {
            distributorAmountConsume.setSc(-amount);
        }
        distributorAmountConsume.setDevId(id);
        distributorAmountConsume.setCreateTime(new Date());
        distributorAmountConsume.setDistributorId(devInfo.getDistributorId());
        distributorAmountConsume.setRemark("负充值" + id + "设备");

        distributorAmountConsumeService.add(distributorAmountConsume);
        DevInfo info = mapper.selectByPrimaryKey(id);
        logDevOptService.add(LogDevOpt.builder()
                .res(id)
                .imei(info.getImei())
                .devId(info.getId())
                .opt("冲负值")
                .createUserId(1)
                .createTime(new Date())
                .build());
    }

    @Override
    public void addMoney(String id, Integer amount) {
        DevInfo devInfo = mapper.selectByPrimaryKey(id);
        DistributorAmountConsume distributorAmountConsume = new DistributorAmountConsume();
        if (devInfo.getBillTypeId().equals(0)) {
            distributorAmountConsume.setLl(amount);
        } else {
            distributorAmountConsume.setSc(amount);
        }
        distributorAmountConsume.setDevId(id);
        distributorAmountConsume.setCreateTime(new Date());
        distributorAmountConsume.setDistributorId(devInfo.getDistributorId());
        distributorAmountConsume.setRemark("充值" + id + "设备");

        distributorAmountConsumeService.add(distributorAmountConsume);
        devApiHelper.addMoney(devInfo.getImei(), amount);
        DevInfo info = mapper.selectByPrimaryKey(id);
        logDevOptService.add(LogDevOpt.builder()
                .res(id)
                .imei(info.getImei())
                .devId(info.getId())
                .opt("冲正值")
                .createUserId(1)
                .createTime(new Date())
                .build());
    }
}
